<template>
  <view class="container">
    <!-- 消息列表 -->
    <scroll-view
      :scroll-into-view="scrollIntoView"
      class="message-list"
      scroll-y
      @scrolltoupper="onLoadMore"
    >
      <view
        v-for="(msg, index) in messages"
        :id="`msg-${index}`"
        :key="msg.id"
        class="message-item"
        :class="{ self: msg.fromUserId === currentUserId }"
      >
        <!-- 头像 -->
        <u-avatar :src="msg.fromUserId === currentUserId ? userAvatar : otherUserAvatar" size="40" />

        <!-- 消息内容 -->
        <view class="message-content">
          <!-- 文本消息 -->
          <view v-if="msg.contentType === 'text'" class="message-bubble text-message">
            {{ msg.content }}
          </view>

          <!-- 图片消息 -->
          <image
            v-else-if="msg.contentType === 'image'"
            :src="msg.mediaUrl"
            class="message-bubble image-message"
            mode="aspectFill"
            @click="previewImage([msg.mediaUrl!], 0)"
          />

          <!-- 语音消息 -->
          <view
            v-else-if="msg.contentType === 'voice'"
            class="message-bubble voice-message"
            @click="playVoice(msg)"
          >
            <u-icon name="volume-fill" size="20"></u-icon>
            <text>{{ msg.duration }}"</text>
          </view>

          <!-- 位置消息 -->
          <view v-else-if="msg.contentType === 'location'" class="message-bubble location-message">
            <u-icon name="map" size="20"></u-icon>
            <text>{{ msg.locationInfo?.address }}</text>
          </view>
        </view>
      </view>

      <!-- 加载更多 -->
      <view v-if="loadingMore" class="loading-more">
        <u-loading mode="circle" size="20"></u-loading>
      </view>
    </scroll-view>

    <!-- 输入栏 -->
    <view class="input-bar">
      <view class="input-actions">
        <u-icon name="photo" size="28" color="#666" @click="sendImage"></u-icon>
        <u-icon name="mic" size="28" color="#666" @click="toggleVoiceMode"></u-icon>
      </view>

      <view class="input-wrapper">
        <textarea
          v-if="!voiceMode"
          v-model="inputText"
          class="message-input"
          placeholder="说点什么..."
          auto-height
          :maxlength="500"
          @confirm="sendTextMessage"
        />
        <view v-else class="voice-input" @touchstart="startRecord" @touchend="endRecord">
          <text>{{ recording ? '松开发送' : '按住说话' }}</text>
        </view>
      </view>

      <view class="send-btn" :class="{ active: canSend }" @click="sendTextMessage">
        发送
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, nextTick, onMounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { useChatStore } from '@/store/chat'
import { useUserStore } from '@/store/user'
import { uploadApi } from '@/api'
import { previewImage as previewImageUtil, chooseImage } from '@/utils/common'
import type { Message } from '@/types'

const chatStore = useChatStore()
const userStore = useUserStore()

// 状态
const conversationId = ref<number>(0)
const userId = ref<number>(0)
const postId = ref<number>(0)
const messages = ref<Message[]>([])
const inputText = ref('')
const voiceMode = ref(false)
const recording = ref(false)
const loadingMore = ref(false)
const scrollIntoView = ref('')
const page = ref(1)

// 语音录制
const recorderManager = uni.getRecorderManager()
const innerAudioContext = uni.createInnerAudioContext()

// 计算属性
const currentUserId = computed(() => userStore.userInfo?.id || 0)
const userAvatar = computed(() => userStore.userInfo?.avatar || '')
const otherUserAvatar = computed(() => {
  // 从会话信息中获取对方头像
  const conv = chatStore.conversations.find(c => c.id === conversationId.value)
  return conv?.otherUser.avatar || ''
})
const canSend = computed(() => inputText.value.trim() !== '')

// 生命周期
onLoad(async (options: any) => {
  conversationId.value = Number(options.conversationId) || 0
  userId.value = Number(options.userId) || 0
  postId.value = Number(options.postId) || 0

  // 如果没有conversationId，需要创建会话
  if (!conversationId.value && userId.value) {
    await createConversation()
  }

  if (conversationId.value) {
    await loadMessages()
    markAsRead()
  }

  // 监听语音录制
  setupRecorder()
})

/**
 * 创建会话
 */
const createConversation = async () => {
  const id = await chatStore.createConversation({
    targetUserId: userId.value,
    postId: postId.value
  })

  if (id) {
    conversationId.value = id
  }
}

/**
 * 加载消息
 */
const loadMessages = async (isLoadMore = false) => {
  if (!conversationId.value) return

  loadingMore.value = isLoadMore

  try {
    const hasMore = await chatStore.fetchMessages(conversationId.value, page.value)

    messages.value = chatStore.currentMessages

    if (isLoadMore) {
      page.value++
    } else {
      // 滚动到底部
      await nextTick()
      scrollToBottom()
    }
  } catch (err) {
    console.error('加载消息失败:', err)
  } finally {
    loadingMore.value = false
  }
}

/**
 * 加载更多历史消息
 */
const onLoadMore = () => {
  loadMessages(true)
}

/**
 * 标记已读
 */
const markAsRead = () => {
  if (conversationId.value) {
    chatStore.markRead(conversationId.value)
  }
}

/**
 * 发送文本消息
 */
const sendTextMessage = async () => {
  if (!canSend.value) return

  const content = inputText.value.trim()
  inputText.value = ''

  const success = await chatStore.sendMessage(conversationId.value, {
    contentType: 'text',
    content
  })

  if (success) {
    messages.value = chatStore.currentMessages
    await nextTick()
    scrollToBottom()
  }
}

/**
 * 发送图片
 */
const sendImage = async () => {
  try {
    const images = await chooseImage(1)
    uni.showLoading({ title: '发送中...' })

    // 上传图片
    const url = await uploadApi.uploadImage(images[0])

    // 发送消息
    await chatStore.sendMessage(conversationId.value, {
      contentType: 'image',
      mediaUrl: url
    })

    messages.value = chatStore.currentMessages
    await nextTick()
    scrollToBottom()

    uni.hideLoading()
  } catch (err) {
    uni.hideLoading()
    console.error('发送图片失败:', err)
  }
}

/**
 * 切换语音模式
 */
const toggleVoiceMode = () => {
  voiceMode.value = !voiceMode.value
}

/**
 * 设置录音监听
 */
const setupRecorder = () => {
  recorderManager.onStop((res) => {
    if (res.duration < 1000) {
      uni.showToast({ title: '说话时间太短', icon: 'none' })
      return
    }

    // 上传并发送语音
    uploadVoice(res.tempFilePath, Math.floor(res.duration / 1000))
  })
}

/**
 * 开始录音
 */
const startRecord = () => {
  recording.value = true
  recorderManager.start({
    format: 'mp3',
    duration: 60000 // 最长60秒
  })
}

/**
 * 结束录音
 */
const endRecord = () => {
  recording.value = false
  recorderManager.stop()
}

/**
 * 上传语音
 */
const uploadVoice = async (tempFilePath: string, duration: number) => {
  try {
    uni.showLoading({ title: '发送中...' })

    // 上传语音文件
    const url = await uploadApi.uploadVoice(tempFilePath)

    // 发送消息
    await chatStore.sendMessage(conversationId.value, {
      contentType: 'voice',
      mediaUrl: url
    })

    messages.value = chatStore.currentMessages
    await nextTick()
    scrollToBottom()

    uni.hideLoading()
  } catch (err) {
    uni.hideLoading()
    console.error('发送语音失败:', err)
  }
}

/**
 * 播放语音
 */
const playVoice = (msg: Message) => {
  if (!msg.mediaUrl) return

  innerAudioContext.src = msg.mediaUrl
  innerAudioContext.play()
}

/**
 * 预览图片
 */
const previewImage = (urls: string[], current: number) => {
  previewImageUtil(urls, current)
}

/**
 * 滚动到底部
 */
const scrollToBottom = () => {
  if (messages.value.length > 0) {
    scrollIntoView.value = `msg-${messages.value.length - 1}`
  }
}
</script>

<style lang="scss" scoped>
.container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: var(--bg-color-page);
}

.message-list {
  flex: 1;
  padding: var(--spacing-md);
}

.message-item {
  display: flex;
  margin-bottom: var(--spacing-lg);
  gap: var(--spacing-sm);

  &.self {
    flex-direction: row-reverse;

    .message-content {
      align-items: flex-end;
    }

    .message-bubble {
      background-color: var(--primary-color);
      color: #ffffff;
    }
  }

  .message-content {
    display: flex;
    flex-direction: column;
    max-width: 60%;
  }

  .message-bubble {
    padding: var(--spacing-md);
    border-radius: var(--radius-md);
    background-color: var(--bg-color);
    word-break: break-all;
  }

  .text-message {
    font-size: 28rpx;
    line-height: 1.6;
  }

  .image-message {
    width: 300rpx;
    height: 300rpx;
    border-radius: var(--radius-md);
  }

  .voice-message {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    min-width: 150rpx;
  }

  .location-message {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
  }
}

.loading-more {
  text-align: center;
  padding: var(--spacing-md);
}

.input-bar {
  display: flex;
  align-items: flex-end;
  padding: var(--spacing-sm) var(--spacing-md);
  background-color: var(--bg-color);
  border-top: 1rpx solid var(--border-color-light);
  gap: var(--spacing-sm);

  .input-actions {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
  }

  .input-wrapper {
    flex: 1;

    .message-input {
      width: 100%;
      max-height: 200rpx;
      padding: 16rpx;
      background-color: var(--bg-color-page);
      border-radius: var(--radius-sm);
      font-size: 28rpx;
    }

    .voice-input {
      padding: 24rpx;
      background-color: var(--bg-color-page);
      border-radius: var(--radius-sm);
      text-align: center;
      font-size: 28rpx;
      color: var(--text-color-secondary);
    }
  }

  .send-btn {
    padding: 16rpx 32rpx;
    background-color: var(--bg-color-page);
    color: var(--text-color-secondary);
    font-size: 28rpx;
    border-radius: var(--radius-sm);

    &.active {
      background-color: var(--primary-color);
      color: #ffffff;
    }
  }
}
</style>
